package org.jeecg.report.util;

import org.jeecg.report.vo.FTQReportColumnVO;
import org.jeecg.report.vo.FTQReportVO;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

import static com.sun.xml.internal.xsom.impl.UName.comparator;

public class ReportUtils {

    public static List<Map<String, Object>> convertToColumnFormat(List<FTQReportVO> reportVOList) {
        // 1. 收集所有日期并排序
        List<String> dates = reportVOList.stream()
                .map(FTQReportVO::getDate)
                .distinct()
                .sorted()
                .collect(Collectors.toList());

        // 2. 按工序分组
//        Comparator<FTQReportVO> comparator = Comparator.comparing(
//                vo -> reportVOList.indexOf(vo.getOp())
//        );
        Comparator<FTQReportVO> comparator = Comparator.comparing(FTQReportVO::getOp, (op1, op2) -> {
            // 提取OP编号进行数值比较
            String num1 = op1.replaceAll("[^0-9]", "");
            String num2 = op2.replaceAll("[^0-9]", "");

            if (num1.isEmpty() || num2.isEmpty()) {
                return op1.compareTo(op2);
            }

            try {
                return Integer.parseInt(num1) - Integer.parseInt(num2);
            } catch (NumberFormatException e) {
                return op1.compareTo(op2);
            }
        });
        Map<String, List<FTQReportVO>> opGroup = reportVOList.stream()
                .sorted(comparator)
                .collect(Collectors.groupingBy(
                        FTQReportVO::getOp,
                        LinkedHashMap::new,
                        Collectors.toList()
                ));
//        Map<String, List<FTQReportVO>> opGroup = reportVOList.stream()
//                .collect(Collectors.groupingBy(FTQReportVO::getOp));

        // 3. 定义需要展示的指标字段
        String[] metrics = {"投入数", "产出良品", "报废数", "报废率", "FTQ"};

        // 4. 构建结果集
        List<Map<String, Object>> result = new ArrayList<>();
        Map<String, Double> hashMap = new HashMap<>();
        opGroup.forEach((op, list) -> {
            // 为每个指标创建独立行
            for (String metric : metrics) {
                Map<String, Object> row = new LinkedHashMap<>();
                // 添加公共列
                row.put("op", op);
                row.put("description", list.get(0).getDescription());
                row.put("metric", metric); // 新增指标类型列

                // 构建日期->指标值的映射
                Map<String, Double> dateValues = list.stream()
                        .collect(Collectors.toMap(
                                FTQReportVO::getDate,
                                vo -> getMetricValue(vo, metric),
                                (oldVal, newVal) -> newVal));
                Double total = 0.0;
                // 计算 total
                if (metric.equals("投入数")|| metric.equals("产出良品")|| metric.equals("报废数")){
                     total = dateValues.values().stream()
                            .mapToDouble(val -> (Double) val)
                            .sum();
                }
                // 填充日期列
                dates.forEach(date ->
                        row.put(date, dateValues.getOrDefault(date, 0.0))
                );
                // 添加 total 列
                row.put("total", total);
                hashMap.put(op+"-"+metric,total);
                result.add(row);
            }
        });
        //根据同样工序的产出良品/投入数计算FTQ
        for (Map<String, Object> stringObjectMap : result) {
            if (stringObjectMap.get("metric").equals("FTQ")) {
                Double t1 = hashMap.get(stringObjectMap.get("op") + "-" + "投入数");
                Double c1 = hashMap.get(stringObjectMap.get("op") + "-" + "产出良品");
                if (t1 != null && t1 != 0.0) {
                    BigDecimal ftq = BigDecimal.valueOf(c1 / t1*100).setScale(2, RoundingMode.HALF_UP);
                    stringObjectMap.put("total", ftq.doubleValue()+"%");
                } else {
                    stringObjectMap.put("total", "0%");
                }
            }
            if (stringObjectMap.get("metric").equals("报废率")) {
                Double t1 = hashMap.get(stringObjectMap.get("op") + "-" + "投入数");
                Double b1 = hashMap.get(stringObjectMap.get("op") + "-" + "报废数");
                if (t1 != null && t1 != 0.0) {
                    BigDecimal scrapRate = BigDecimal.valueOf(b1 / t1*100).setScale(2, RoundingMode.HALF_UP);
                    stringObjectMap.put("total", scrapRate.doubleValue()+"%");
                } else {
                    stringObjectMap.put("total", "0%");
                }
            }
        }
        return result;
    }

    private static Double getMetricValue(FTQReportVO vo, String metric) {
        switch (metric) {
            case "投入数":
                return Double.valueOf(vo.getQty());
            case "产出良品":
                return Double.valueOf(vo.getOk());
            case "报废数":
                return Double.valueOf(vo.getScrap());
            case "报废率":
                return vo.getObsolescence();
            case "FTQ":
                return vo.getFtq();
            default:
                return 0.0;
        }
   }
}